home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / amitcp / amitcp-src-22.lha / AmiTCP-2.2 / src / appl / napsaterm / rcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-07  |  4.5 KB  |  228 lines

  1. RCS_ID_C "$Id: rcmd.c,v 1.6 1993/10/08 00:02:44 ppessi Exp $";
  2. /*
  3.  * rcmd.c --- remote login connection 
  4.  *
  5.  * Author: ppessi <Pekka.Pessi@hut.fi>
  6.  *
  7.  * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  8.  *                    Helsinki University of Technology, Finland.
  9.  *                    All rights reserved.
  10.  *
  11.  * Created      : Tue May 18 01:59:25 1993 ppessi
  12.  * Last modified: Wed Sep 22 19:57:07 1993 ppessi
  13.  *
  14.  * $Log: rcmd.c,v $
  15.  * Revision 1.6  1993/10/08  00:02:44  ppessi
  16.  * Fixed OOB handling when input buffer overflows.
  17.  *
  18.  * Revision 1.4  1993/08/12  06:19:13  jraja
  19.  * Updated the email-address.
  20.  *
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include "nifty.h"
  26. #include "amiga.h"
  27. #include "nio.h"
  28. #include <ctype.h>
  29. #include <errno.h>
  30. #include <string.h>
  31. #include <sys/ioctl.h>
  32.  
  33. struct Library *SocketBase;
  34.  
  35. #if __SASC
  36. #include <proto/socket.h>
  37. #elif __GNUC__
  38. #include <inline/socket.h>
  39. #else
  40. #include <clib/socket_protos.h>
  41. #endif
  42. #include "rlogin.h"
  43.  
  44. #define BUFSIZE 256
  45.  
  46. char *username = NULL;
  47.  
  48. int errno;
  49.  
  50. BYTE IO_bit = -1;
  51. BYTE URG_bit = -1;
  52. ULONG SIGURG = 0;
  53.  
  54. char okwinch = 0;
  55.  
  56. struct winsize_packet winsize =
  57. { 0377, 0377, 's', 's', 0, 0, 0, 0 };
  58.  
  59.  
  60. long rresvport(long *alport);
  61.  
  62. void 
  63. CloseSocketBase(void)
  64. {
  65.   if (SocketBase) CloseLibrary(SocketBase), SocketBase = NULL;
  66.   if (IO_bit != -1) FreeSignal(IO_bit), IO_bit = -1;
  67.   if (URG_bit != -1) FreeSignal(URG_bit), URG_bit = -1;
  68. }
  69.  
  70. void
  71. rsendwsize(int s) 
  72. {
  73.     send(s, &winsize, sizeof(winsize), 0);
  74. }
  75.  
  76. int 
  77. rread(long s, char *buf, int length)
  78. {
  79.     char tiop;
  80.     int n = 0, m; 
  81.     int wasting = 0;
  82.     char waste[BUFSIZE];
  83.  
  84.     for (;;) {
  85.     /* We are at OOB data? */
  86.     ioctl(s, SIOCATMARK, &m);
  87.     if (m) {
  88.         m = recv(s, &tiop, 1, MSG_OOB);
  89.         if (m < 0) break;
  90.  
  91.         if (tiop & TIOCPKT_WINDOW) {
  92.         /* Let server know about window size changes */
  93.         okwinch = 1;    
  94.         rsendwsize(s);
  95.         }
  96.         /* Here we might want to handle other bits */
  97.         if (tiop & TIOCPKT_FLUSHWRITE) {
  98.         for (;;) {
  99.             if (ioctl(s, SIOCATMARK, &m) < 0) {
  100.             (void)perror(PROGNAME ": ioctl");
  101.             n = -1;
  102.             break;
  103.             }
  104.             if (m) break;
  105.             n = recv(s, waste, sizeof (waste), 0);
  106.             if (n <= 0) break;
  107.         }
  108.         n = 0;
  109.         }
  110.  
  111.         /* SIGIO is not sent without this */
  112. #if USE_FIONBIO
  113.         recv(s, waste, sizeof(waste), 0);
  114. #else
  115.         recv(s, waste, 0, 0);
  116. #endif
  117.         return n;
  118.     }
  119.     if ((m = recv(s, buf, length, 0)) < 0) 
  120.         break;
  121.     if (wasting) 
  122.         continue;
  123.     n += m; buf +=m; length -= m;
  124.     if (length > 0) continue;
  125.     wasting = 1; buf = waste; length = sizeof(waste); 
  126.     } 
  127.  
  128.     return n;
  129. }
  130.  
  131. /* 
  132.  * rcmd
  133.  *     Connect to the server using a privileged port
  134.  */
  135. int 
  136. rcmd(char **host, u_short rport, 
  137.      const char *locuser, const char *remuser, const char *term)
  138. {
  139.     int s;
  140.     struct sockaddr_in sin;
  141.     struct in_addr saddr;
  142.     char c;
  143.     struct hostent *hp;
  144.     int lport = IPPORT_RESERVED - 1;
  145.     struct Task *pid = FindTask(NULL);
  146.  
  147.     sin.sin_len = sizeof(sin);
  148.     sin.sin_family = AF_INET;
  149.     sin.sin_addr.s_addr = inet_addr(*host);
  150.     if (sin.sin_addr.s_addr == (u_int)-1) {
  151.     hp = gethostbyname(*host);
  152.     if (hp == 0) {
  153.         fputs(*host, stderr);
  154.         fputs(": unknow target.\n", stderr);
  155.         return (-1);
  156.     }
  157.     sin.sin_family = hp->h_addrtype;
  158.     bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  159.     }
  160.     sin.sin_port = rport;
  161.  
  162.     /* get a socket with a privileged port */
  163.     s = rresvport(&lport);
  164.     if (s < 0) {
  165.     perror("rcmd: socket");
  166.     return (-1);
  167.     }
  168.  
  169.     ioctl(s, FIOSETOWN, (char*)&pid);
  170.  
  171.     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
  172.     perror(*host);
  173.     return (-1);
  174.     }
  175.  
  176.     send(s, "", 1, 0);
  177.     send(s, locuser, strlen(locuser)+1, 0);
  178.     send(s, remuser, strlen(remuser)+1, 0);
  179.     send(s, term, strlen(term)+1, 0);
  180.     if (recv(s, &c, 1, 0) != 1) {
  181.     perror(*host);
  182.     goto bad;
  183.     }
  184.     if (c != 0) {
  185.     while (recv(s, &c, 1, 0) == 1) {
  186.         (void) fputc(c, stderr);
  187.         if (c == '\n')
  188.         break;
  189.     }
  190.     goto bad;
  191.     }
  192.     return s;
  193.  bad:
  194.     (void) CloseSocket(s);
  195.     return (-1);
  196. }
  197.  
  198. /*
  199.  * Bind a socket with privileged port
  200.  */
  201. long
  202. rresvport(long *alport)
  203. {
  204.   struct sockaddr_in sin;
  205.   int s;
  206.  
  207.   sin.sin_family = AF_INET;
  208.   sin.sin_addr.s_addr = INADDR_ANY;
  209.   s = socket(AF_INET, SOCK_STREAM, 0);
  210.   if (s < 0)
  211.     return (-1);
  212.   for (;;) {
  213.     sin.sin_port = htons((u_short)*alport);
  214.     if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  215.       return (s);
  216.     if (errno != EADDRINUSE) {
  217.       (void) close(s);
  218.       return (-1);
  219.     }
  220.     (*alport)--;
  221.     if (*alport == IPPORT_RESERVED/2) {
  222.       (void) close(s);
  223.       errno = EAGAIN;        /* close */
  224.       return (-1);
  225.     }
  226.   }
  227. }
  228.